package com.gopay.scheduler.service.sms.impl;

import com.gopay.common.constants.sms.SmsMassEnum;
import com.gopay.common.cps.service.sms.SmsMassBaseService;
import com.gopay.common.domain.sms.SmsMassContent;
import com.gopay.common.order.dao.CommonQueryDAO;
import com.gopay.scheduler.common.CronSmsMassConstants;
import com.gopay.scheduler.manager.sms.SmsMassManager;
import com.gopay.scheduler.service.sms.CronSmsMassService;
import com.gopay.scheduler.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;

/**
 * 移动短信群发:
 * 方案一MQ: 单条发送cron-(cps-active)-sms;对于短信状态很好捕捉和补偿;但是不确定sms系统能否承受此并发请求;所以不考虑此方案
 * 方案二MQ: 批量发送cron-(cps-active)-sms;对于短信状态捕捉和异常补偿;事务问题不好解决;所以不考虑此方案(有时间可以考虑这么开发)
 * 方案三: 在corn内消化此问题;避免分布式事务,同时可以进行批量发送;
 * 1,但是对于要延长smsJob的发送间隔,避免出现重复更新状态造成公司损失;
 * 2,corn中断造成sms状态为中间态的情况
 * 补偿机制:因为异常情况为少数,且此功能不涉及交易,考虑短信发送的金额,不建议多次补偿(耗性能),如补偿中出异常即不再重新发送;
 * 补偿机制和此任务时间将错开
 * 设置超时机制,避免任务堆积
 * create by baiyunpeng 2017/07/07 短信群发项目service
 */
@Service
public class CronSmsMassServiceImpl implements CronSmsMassService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private SmsMassBaseService smsMassBaseService;
    @Autowired
    private CommonQueryDAO commonQueryDAO;
    @Autowired
    private SmsMassManager smsMassManager;
    private @Value("#{webProperties['smsMassCompensateJobLoop']}") Integer compensateSmsLoop;

    @Override
    public void sendMass() {
        try {
            String mm = DateUtils.format(new Date(), "mm");
            int currentMinutes = Integer.parseInt(mm);
            if((currentMinutes-1) % compensateSmsLoop == 0 || (currentMinutes+1) % compensateSmsLoop == 0){
                logger.info(String.format("短信群发定时任务发送日期为{%s},避让时间点{%s},避让短信群发补偿Job,SmsMassJob暂停执行",DateUtils.format(new Date(),"yyyyMMdd"),mm));
                return;
            }
            List<SmsMassContent> willBeSendList = smsMassBaseService.selectTheSmsWillBeSendByPage(1,CronSmsMassConstants.PAGESIZE_CONTENT);
            if(willBeSendList==null || willBeSendList.size()==0){
                CronSmsMassConstants.SMS_MASS_COMPENSATE_START = true;
                logger.info(String.format("短信群发定时任务发送日期为{%s},今日无数据,任务不执行",DateUtils.format(new Date(),"yyyyMMdd")));
                return;
            }
            long startSw = System.currentTimeMillis();
            logger.info("短信群发定时任务-------execute");
            for (SmsMassContent willBeSend : willBeSendList){
                if(new Date().compareTo(willBeSend.getSendTime())<0) {
                    logger.info(String.format("短信序号为%s的短信定时任务发送当前时间{%s}小于定时发送时间{%s},不执行发送",willBeSend.getSmsId()
                    ,DateUtils.format(new Date(), "yyyyMMddHHmmss"),DateUtils.format(willBeSend.getSendTime(), "yyyyMMddHHmmss")));
                    continue;
                }
               // if (smsMassManager.judgeTime2ExecuteUpd(willBeSend,SmsMassEnum.SEND_OVER_TIME.getValue(),2)) continue;
                smsMassBaseService.updateMassSatus(SmsMassEnum.SEND_SENDING.getValue(),willBeSend.getSmsId());
                CronSmsMassConstants.SMS_MASS_COMPENSATE_START = false;
                selectWillBeSendSmsByPage(willBeSend.getSmsId(), willBeSend.getContent());
            }
            long stopSw = System.currentTimeMillis();
            logger.info("短信群发共耗费秒[{}]",(( stopSw*1.0 - startSw) / 1000));
        } catch (Exception e) {
            logger.error("短信群发定时任务异常",e);
        }
    }
    private void selectWillBeSendSmsByPage(String smsId,String content) throws Exception {
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT SMS_MASS_ID , PHONE_NUM FROM SMS_MASS_DETAIL WHERE SMS_CONTENT_ID='"+smsId+"' AND SEND_STATUS='0' ORDER BY CREATE_TS DESC  ");
        smsMassManager.packageList(commonQueryDAO.findBySql(sql.toString()),smsId,content,CronSmsMassConstants.SMS_NORMAL);
    }
}
